 
/* $Id: history.c 8 2009-12-27 16:54:50Z calicant $ */

#include "edilana.h"

extern struct Setup *conf;

/*#define DEBUG*/

#define MAXLINES    500
#define MAXL         90

#include <time.h>

void prompt (void)
{

    if (conf->promptora) {
        struct tm *tp;
        long c;
        
        time(&c);
        tp = localtime(&c);
        printf("%02d:%02d", tp->tm_hour, tp->tm_min);
    }
    printf("\x1b[%dm%% \x1b[0m", conf->colorprompt);

}

#define left(n)     printf("\033[%dD",n)
#define right(n)    printf("\033[%dC",n)
#define del_line()  printf("\033[K")

static char* history_buff [MAXLINES];

#include "tasti.h"

int LineEdit (char *sott, char *lista, int flag)
{
char        stemp[MAXSTRLEN], *p, *r;
char        ch = 0, oldch;
int     i = 0, l = 0, d;
static int  index = 0, inizio = 0, move = 0, piena = 0;

FILE    *fh;
int llemma = 0, lout = 0, lpat = 0, start = 0;
char    newpat[MAXSTRLEN], pat[MAXSTRLEN];


    if (flag) {
        if (piena) l = MAXLINES;
        else l = index;
        for (i = 0; i < l; i++)
            free(history_buff[i]);
        return 0;
    }
    fh = fopen(lista,"r");

    prompt();

    *sott = '\0';

    for (;;) {
        sopra:

        oldch = ch;
        ch = tasto();

        if (ch == CURS_UP || ch == CURS_DOWN || ch == CTRL_L || ch == CTRL_P ||
            ch == CTRL_J || ch == CTRL_O)  {
            if (ch == CURS_UP || ch == CTRL_L || ch == CTRL_P) {
                if (move == inizio) continue;
                if (ch == CTRL_L) move = inizio;
                                else if (ch == CTRL_P) {
                    if (!i) continue;
                    while (move != inizio) {
                        move--;
                        if (move < 0)
                            move = MAXLINES - 1;
                        if (!strncmp(history_buff[move],
                            sott, i))
                                break;
                    }
                    if (move == inizio)
                        if (strncmp(history_buff[move],
                            sott, i)) {
                            move = index;
                            continue;

                        }
                }
                else {
                    move--;
                    if (move < 0) move = MAXLINES - 1;
                }
            }
            else if (ch == CURS_DOWN || ch == CTRL_J || ch == CTRL_O) {
                if (ch == CTRL_J) {
                    if (i) left(i);
                    del_line();
                    sott[i] = '\0';
                    printf("%s",sott);
                    l = i;
                    move = index;
                    continue;
                }
                if (move == index - 1 || move == index ||
                    (!index && move == MAXLINES-1))
                        continue;
                if (ch == CTRL_O) {
                    move = index - 1;
                    if (!index) move = MAXLINES-1;
                }
                else {
                    move++;
                    if (move == MAXLINES) move = 0;
                }
            }
            if (i) left(i);
            del_line();
            strcpy(sott,history_buff[move]);
            l = strlen(sott);
            printf("%s",sott);
            if (ch == CTRL_P && l > i)
                left(l-i);
            else i = l;
            continue;
        }

        switch(ch) {
            case CURS_RIGHT:
            case CTRL_E:
            case CTRL_F:
                fine_linea:
                if (ch == CTRL_E) {
                    if (i == l) break;
                    right(l-i);
                    i = l;
                    break;
                }
                if (ch == CTRL_F) {
                    if (sott[i+1] == '\0') break;
                    if ((r = strchr(&sott[i+1], ' '))
                        != NULL) {
                        d = r - &sott[i+1] + 1;
                        i += d;
                        right(d);
                    }
                    else {
                        ch = CTRL_E;
                        goto fine_linea;
                    }
                    break;
                }
                if (i == MAXL || i == l) break;
                i++;
                                right(1);
                break;
            case CURS_LEFT:
            case CTRL_A:
            case CTRL_B:
                inizio_linea:
                if (ch == CTRL_A) {
                    if (!i) break;
                                        left(i);
                    i = 0;
                    break;
                }
                if (ch == CTRL_B) {
                    strcpy(stemp,sott);
                    stemp[i] = '\0';
                    Inverte(stemp);
                    if ((r = strchr(stemp, ' '))
                        != NULL) {
                        d = r - stemp + 1;
                        i -= d;
                                                left(d);
                    }
                    else {
                        ch = CTRL_A;
                        goto inizio_linea;
                    }
                    break;
                }
                if (i == 0)
                    break;
                i--;
                                left(1);
                break;
/*
            case CTRL:
                if (i) left(i);
                del_line();
                i = 0;
                l = 0;
                sott[0] = '\0';
                move = index;
                break;
*/
            case RETURN:
                printf("\n");
                if (fh) fclose(fh);
                if (!l) {
                    strcpy(sott,"\n");
                    return 0;
                }
                if ((p = spazioStringa(sott)) == NULL)
                    return MANCA_MEMORIA;
                history_buff[index++] = p;
                if (index == MAXLINES) {
                    #ifdef DEBUG
                    printf("\n*** piena\n");
                    #endif
                    piena  = 1;
                    index  = 0;
                }
                move = index;
                if (piena) {
                    inizio = index + 1;
                    if (inizio == MAXLINES)
                        inizio = 0;
                }
                strcat(sott,"\n");
                #ifdef DEBUG
                printf("\nmv %d ind %d ini %d l %d i %d %s\n",
                    move, index, inizio, l, i, sott);
                #endif
                return 0;
            case BACKSPACE: case BACKSPACE_AGAIN:
                if (!i) break;
                if (i == l) {
                    sott[--l] = '\0';
                    left(1);
                    printf(" ");
		    fflush(stdout);
                    left(1);
                    i--;
                }
                else {
                    strcpy(stemp,&sott[i]);
                    sott[--i] = '\0';
                    strcat(sott,stemp);
                    left(1);
                    printf("%s ",stemp);
            fflush(stdout);
                    left(l-i);
                    l--;
                }
                break;
/*
            case DEL:
                if (i == l) break;
                if (i == l - 1) {
                    sott[i] = '\0';
                    l--;
                    printf(" ");
                    left(1);
                    break;
                }
                strcpy(stemp, &sott[i+1]);
                sott[i] = '\0';
                strcat(sott,stemp);
              right(1);
                printf("%s ",stemp);
                left(l-i);
                l--;
                break;
*/
        case CTRL_T:
                if (fh) fclose (fh);
                fh = fopen(NOMECANDI, "r");
                continue;
        case TAB:
            if (fh == NULL) continue;
            if (oldch != TAB) {
                fseek(fh, 0, 0);
                lout = 0;
                start = i;
                stemp[start] = '\0';
                while (--start >= 0 && sott[start] != ' ')
                    stemp[start] = sott[start];
                if (start || (!start && sott[start] == ' '))
                    start++;
                strcpy(newpat, &stemp[start]);
                strcpy(pat, newpat);
                lpat = strlen(newpat);
                d = -1;
                                #ifdef DEBUG
                printf("\npat = %s s %d\n",pat,start);
                                #endif
            }
            while(fgets(stemp,MAXSTRLEN,fh) != NULL) {
                            if ((llemma = strncmp(stemp,pat,lpat)) > 0)
                    break;
                else if (llemma < 0)
                    continue;
                llemma = strlen(stemp) - 1;
                stemp[llemma] = '\0';
                if (oldch == TAB) {
                    if (start != i && d) {
                        left(d);
                        i -= d;
                    }
                    sott[start] = '\0';
                    strcat(sott,&stemp[lpat]);
                    strcat(sott,newpat);
                    del_line();
                    printf("%s",&sott[start]);
                    d = llemma - lpat;
                    if (lout) left(lout);
                    i += d;
                    l = strlen(sott);
                    goto sopra;
                }
                d++;
                llemma += 2;
                if (llemma + lout < 78)
                    lout += llemma;
                else {
                    printf("\n");
                    lout = llemma;
                                }

                if (!d) {
                    strcpy(newpat, stemp);
                    continue;
                }
                else {
                    if (d == 1)
                        printf("\n%s  ", newpat);
                    printf("%s  ", stemp);
                }
                p = newpat + lpat;
                r = stemp + lpat;
                l = lpat;
                while (*p++ == *r++)
                    newpat[l++] = *(p-1);
                newpat[l] = '\0';
            }
            fseek(fh, 0, 0);
            if (oldch != TAB) {
                strcpy(pat, newpat);
                lpat = strlen(pat);
                strcpy(newpat,&sott[i]);
                sott[i] = '\0';
                if (lout && d)
                    printf("\n%s",sott);
                sott[start] = '\0';
                strcat(sott,pat);
                strcat(sott,newpat);
                l = strlen(sott);
                lout = strlen(newpat);
                printf("%s",&sott[i]);
                i = l - lout;
                if (lout) left(lout);
                start = i;
            }
                        break;
            default:
                if (l == MAXL) break;
                if (l == i) {
                    sott[l++] = ch;
                    sott[l] = '\0';
                    i++;
                    printf("%c",ch);
                }
                else {
                    strcpy(stemp,&sott[i]);
                    sott[i++] = ch;
                    sott[i] = '\0';
                    strcat(sott,stemp);
                    printf("%c%s",ch,stemp);
                    left(l-i+1);
                    l++;
                }
                break;
        }
    }

}
